package org.jeecg.common.util.security;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.annotation.Logical;
import org.jeecg.common.constant.enums.RoleCode;
import org.jeecg.common.system.vo.LoginUser;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户信息工具
 *
 * @author qiang.zhou
 * @createtime 2023-03-07  11:08
 */
public class SecurityUtil extends SecurityUtils {

    public static boolean checkRole(RoleCode... roleCodes) {
        if (null == roleCodes) {
            return false;
        }
        return checkRole(Arrays.stream(roleCodes).map(RoleCode::getCode).collect(Collectors.toList()), Logical.OR);
    }

    public static boolean checkRole(String... roleCodes) {
        if (null == roleCodes) {
            return false;
        }
        return checkRole(Arrays.stream(roleCodes).collect(Collectors.toList()), Logical.OR);
    }

    /**
     * 检查用户权限
     * @author: qiang.zhou
     * @date: 2023/3/7 16:46
     * @param roleCodeList 
     * @param logical  校验规则
     * @return boolean       
     **/
    public static boolean checkRole(List<String> roleCodeList, Logical logical) {
        try {
            if (roleCodeList.size() == 1) {
                getSubject().checkRole(roleCodeList.get(0));
                return true;
            }
            if (Logical.AND.equals(logical)) {
                getSubject().checkRoles(roleCodeList);
                return true;
            }
            if (Logical.OR.equals(logical)) {
                // Avoid processing exceptions unnecessarily - "delay" throwing the exception by calling hasRole first
                boolean hasAtLeastOneRole = false;
                for (String role : roleCodeList) {
                    if (getSubject().hasRole(role)) {
                        hasAtLeastOneRole = true;
                    }
                }
                // Cause the exception if none of the role match, note that the exception message will be a bit misleading
                if (!hasAtLeastOneRole) {
                    getSubject().checkRole(roleCodeList.get(0));
                }
            }
            return true;
        } catch (AuthorizationException e) {
            return false;
        }
    }

    public static LoginUser getLoginUser() {
        return  (LoginUser) SecurityUtils.getSubject().getPrincipal();
    }

    public static String getUserId() {
        LoginUser user = getLoginUser();
        return user.getId();
    }

    public static String getUsername() {
        LoginUser user = getLoginUser();
        return user.getUsername();
    }

    public static String getPhone() {
        LoginUser user = getLoginUser();
        return user.getPhone();
    }


}
